home *** CD-ROM | disk | FTP | other *** search
- static char *sccsid = "@(#)type.c 1.7u (UCF) 82/12/15";
- /*
- * TYPE - types regular or squeezed files
- *
- * Compile as follows:
- * cc [-DVAX] -O type.c -o type
- * (define VAX only if running on VAX)
- *
- Derived from cnode 'cat', typesq, and others. W. Earnest 5/28/82
- Credit to the following and others for parts of the software:
- Dick Greenlaw(usq)
- Bob Mathias(typesq)
- Steve Passe(cnode)
- Joe Shannon(cnode)
- Chuck Forsberg (Unix version)
-
- Type recognizes CPMEOF (0x1A) on all files. A header line is printed
- for each file. If the last text character of a file is not linefeed,
- one is output before the header line for the next file. If the file is
- squeezed, the original filename is printed. Quit causes type to
- advance to the next file.
-
- */
-
- #include <stdio.h>
- #include <signal.h>
- #define ERROR (-1)
- #define OK 0
- #define CPMEOF 0x1A
- #define PATHLEN 128
-
- #define RECOGNIZE 0xFF76/* unlikely pattern */
- #define DLE 0x90/* repeat byte flag */
- #define SPEOF 256/* special endfile token */
- #define NUMVALS 257/* 256 data values plus SPEOF*/
- #define LARGE 30000
-
- #ifdef VAX/* simulate 16-bit integers and define type for uniformity */
- typedef short INT;
- #else/* if PDP-11 (or whatever), they were already 16 bits */
- typedef int INT;
- #endif
-
- struct _sqleaf {/* Decoding tree */
- INT _children[2];/* left, right */
- };
- struct _sqleaf Dnode[NUMVALS - 1];
-
- INT early_exit = 0;
- INT lastchar = '\n';/* controls whether we need an extra nl after file */
- FILE *infile;
- char stobuf[BUFSIZ];/* use buffered output for efficiency */
-
- INT Bpos;/* last bit position read */
- INT Curin;/* last byte value read */
- INT Repct;/* Number of times to retirn value */
- INT Value;/* current byte value or EOF */
-
- INT getcr(), getuhuff();
-
- snextfil()
- {
- signal(SIGQUIT, snextfil);
- ++early_exit;
- }
-
- main(p_argc, p_argv)
- INT p_argc;
- char **p_argv;
- {
- char file[PATHLEN];
- register INT c, d, x;
-
-
- if (signal(SIGQUIT, snextfil)==SIG_IGN)
- signal(SIGQUIT, SIG_IGN);
- setbuf(stdout, stobuf);
- setbuf(stderr, 0);
-
- if (p_argc < 2) {
- fprintf(stderr, "Usage: type file ...\n");
- exit(1);
- }
-
- for (x = 1;x < p_argc;++x) {
- if(early_exit || lastchar != '\n')
- printf("\n");
- d= 39 - strlen(p_argv[x]);
- for (c=d; --c>=0 ;)
- putchar('=');
- printf(" %s ",p_argv[x]);
- for (c=d; --c>=0 ;)
- putchar('=');
- putchar('\n');
- fflush(stdout);
- early_exit = 0;
- switch (catvalid(file, p_argv[x])) {
- case 'q':
- switch (qsend(file)) {
- case ERROR:
- break;
- case 'a':
- send_text(file);
- }
- break;
- case 'a':
- send_text(file); break;
- case 'x':
- break;
- }
- }
- return (OK);
- }
-
- send_text(file)
- char *file;
- {
- register INT c, lc;
-
- while( ((c = getc(infile)) != EOF) && c != CPMEOF && (!early_exit) )
- putchar(lc=c);
- lastchar=c;
- fclose(infile);
- fflush(stdout);
- return (OK);
- }
-
- catvalid(pname, name)
- char *pname;
- char *name;
- {
- if((infile=fopen(name, "r"))==NULL) {
- fprintf(stderr, "type: Can't open %s\n", name);
- return ERROR;
- }
- strcpy(pname, name);
- return ('q');
- }
-
- /*
- The following code is primarily from typesq.c and utr.c. Typesq
- is a modification of USQ by Dick Greenlaw. Those modifications (usq
- to typesq) were made by Bob Mathias, I am responsible for the butchery
- done to make it work with cat.
-
- */
-
- qsend(fname)
- char *fname;
- {
- register INT i, c, lc;
- register char *p;
- register INT numnodes;/* size of decoding tree */
- char origname[PATHLEN];/* Original file name */
-
- init_cr(); init_huff();
-
- if(portgetw(infile) != RECOGNIZE) {/* Process header */
- rewind(infile);
- return 'a';/* not squeezed after all */
- }
- portgetw(infile);/* discard checksum */
- p = origname;/* Get original file name */
- do {/* send it to array */
- *p = getc(infile);
- } while(*p++ != '\0');
-
- numnodes = portgetw(infile);
- if(numnodes < 0 || numnodes >= NUMVALS) {
- fprintf(stderr, "%s has invalid decode tree size\n", fname);
- fclose(infile);
- return ERROR;
- }
- /* Initialize for possible empty tree (SPEOF only) */
- Dnode[0]._children[0] = -(SPEOF + 1);
- Dnode[0]._children[1] = -(SPEOF + 1);
-
- for(i = 0; i < numnodes; ++i) {/* Get decoding tree from file */
- Dnode[i]._children[0] = portgetw(infile);
- Dnode[i]._children[1] = portgetw(infile);
- }
- /* Get translated output bytes and write file */
- printf("\n%s -> %s\n\n",fname,origname);
- while( ((c = getcr(infile)) != EOF) && c != CPMEOF && (!early_exit) )
- putchar(lc=c);
- lastchar=lc;
- fclose(infile);
- fflush(stdout);
- return OK;
- }
- /*** from utr.c - */
- /* initialize decoding functions */
-
- init_cr()
- {
- Repct = 0;
- }
-
- init_huff()
- {
- Bpos = 99;/* force initial read */
- }
-
- /* Get bytes with decoding - this decodes repetition,
- * calls getuhuff to decode file stream into byte
- * level code with only repetition encoding.
- *
- * The code is simple passing through of bytes except
- * that DLE is encoded as DLE-zero and other values
- * repeated more than twice are encoded as value-DLE-count.
- */
-
- INT
- getcr()
- {
- register INT c;
-
- if(Repct > 0) {
- /* Expanding a repeated char */
- --Repct;
- return Value;
- } else {
- /* Nothing unusual */
- if((c = getuhuff()) != DLE) {
- /* It's not the special delimiter */
- Value = c;
- if(Value == EOF)
- Repct = LARGE;
- return Value;
- } else {
- /* Special token */
- if((Repct = getuhuff()) == 0)
- /* DLE, zero represents DLE */
- return DLE;
- else {
- /* Begin expanding repetition */
- Repct -= 2;/* 2nd time */
- return Value;
- }
- }
- }
- }
- /* Decode file stream INTo a byte level code with only
- * repetition encoding remaining.
- */
-
- INT
- getuhuff()
- {
- register INT i;
- register INT bitval;
-
- /* Follow bit stream in tree to a leaf*/
- i = 0;/* Start at root of tree */
- do {
- if(++Bpos > 7) {
- if((Curin = getc(infile)) == ERROR)
- return ERROR;
- Bpos = 0;
- /* move a level deeper in tree */
- i = Dnode[i]._children[1 & Curin];
- } else
- i = Dnode[i]._children[1 & (Curin >>= 1)];
- } while(i >= 0);
-
- /* Decode fake node index to original data value */
- i = -(i + 1);
- /* Decode special endfile token to normal EOF */
- i = (i == SPEOF) ? EOF : i;
- return i;
- }
- /*
- * Machine independent getw which always gets bytes in the same order
- * as the CP/M version of SQ wrote them
- */
- portgetw(f)
- FILE *f;
- {
- register INT c;
-
- c = getc(f)&0377;
- return c + (getc(f)<<8);
- }
-